template<class T>
class ObjectPool
{
private:
    size_t cap;
    enum{DEFAULT_CAP = 1000};
    char* memory;
    void* freeList;
    struct ExtendList{
        char* ptr;
        ExtendList* next;
    }* extendList;
    size_t trueSize;
public:
    ObjectPool(size_t sz = DEFAULT_CAP):cap(sz){
        trueSize = sizeof(T) < sizeof(void*) ? sizeof(void*) : sizeof(T);
        memory = (char*)malloc(trueSize * cap);
        extendList = nullptr;
        freeList = nullptr;
        for(size_t i = 0; i < cap; i++){
            *((void**)(memory + i * trueSize)) = freeList;
            freeList = memory + i * trueSize;
        }
    }
    ~ObjectPool(){
        if(memory){
            free(memory);
            memory = nullptr;
        }
        ExtendList* node = extendList;
        while(node){
            ExtendList* next = node->next;
            if(node->ptr)
                free(node->ptr);
            delete node;
            node = next;
        }
    }
    T* New(){
        T* ptr = nullptr;
        if(!freeList){
            Extend(DEFAULT_CAP);
        }
        ptr = (T*)freeList;
        freeList = *((void**)freeList);
        new(ptr) T();
        return ptr;
    }
    void Delete(T* ptr){
        ptr->~T();
        *((void**)ptr) = freeList;
        freeList = ptr;
    }
    void Extend(size_t num){
        char* ptr = (char*)malloc(trueSize * num);
        for(size_t i = 0; i < num; i++){
            *((void**)(ptr + i * trueSize)) = freeList;
            freeList = ptr + i * trueSize;
        }
        ExtendList* node = new ExtendList;
        node->ptr = ptr;
        node->next = extendList;
        extendList = node;
    }
};
